package com.dkd.manage.task.allocator.algorithm;

import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

@Slf4j
public class SimulatedAnnealingSelector {

    public Long select(Map<Long, Double> scores, List<Long> candidateIds) {
        log.info("开始模拟退火选择，候选人数: {}", candidateIds.size());

        if (candidateIds.isEmpty()) {
            return null;
        }

        double temperature = 100.0;
        double coolingRate = 0.95;
        double minTemperature = 1.0;

        // 初始解
        Long currentSolution = candidateIds.get((int) (Math.random() * candidateIds.size()));
        double currentEnergy = -scores.getOrDefault(currentSolution, 5.0);

        Long bestSolution = currentSolution;
        double bestEnergy = currentEnergy;

        while (temperature > minTemperature) {
            // 生成邻域解
            Long nextSolution = candidateIds.get((int) (Math.random() * candidateIds.size()));
            double nextEnergy = -scores.getOrDefault(nextSolution, 5.0);

            double energyDelta = nextEnergy - currentEnergy;

            // 接受更优解，或者以一定概率接受劣解
            if (energyDelta < 0 || Math.random() < Math.exp(-energyDelta / temperature)) {
                currentSolution = nextSolution;
                currentEnergy = nextEnergy;

                // 更新最优解
                if (currentEnergy < bestEnergy) {
                    bestSolution = currentSolution;
                    bestEnergy = currentEnergy;
                }
            }

            // 降温
            temperature *= coolingRate;
        }

        log.info("模拟退火选择完成，选择员工: {}", bestSolution);
        return bestSolution;
    }
}